/********************************************************************
	Rhapsody	: 7.5 
	Login		: KBE
	Component	: DefaultComponent 
	Configuration 	: CodeConfig
	Model Element	: SocketReactorImplementation
//!	Generated Date	: Wed, 19, Sep 2012  
	File Path	: DefaultComponent\CodeConfig\SocketReactorImplementation.cpp
*********************************************************************/

//## auto_generated
#include "SocketReactorImplementation.h"
//## dependency SimulatorReactorImplementation
#include "SimulatorReactorImplementation.h"
//## dependency SimulatorReactorImplementation
class SimulatorReactorImplementation;

//## package Default

//## class SocketReactorImplementation
SocketReactorImplementation::SocketReactorImplementation() {
    //#[ operation SocketReactorImplementation()
    handles = 0;
    numHandles = 0;
    //#]
}

void SocketReactorImplementation::handleEvents(int time) {
    //#[ operation handleEvents(int)
    // Initialize fd sets
    FD_ZERO(&readfds); // Connect and read
    FD_ZERO(&writefds); // Write
    FD_ZERO(&exceptfds); // Errors
    numHandles = 0;
    createHandleList();
    Select(0); 
    //#]
}

void SocketReactorImplementation::Select(int timeout) {
    //#[ operation Select(int)
    timeval to;
    to.tv_sec = timeout;
    to.tv_usec = 0;
    
    printf("Select \n");
    if (select(0, &readfds, &writefds, &exceptfds, timeout == 0 ? 0 : &to) > 0) 
    {
    	// Enumerates all sockets to handle
    	for (int i = 0; i < numHandles; i++)
    	{
    		HANDLE h = handles[i];
    		Event_Type type = INVALID_EVENT;
    		if (FD_ISSET(h, &readfds))
    		{
    			type = ACCEPT_EVENT;
    		}
    		else if (FD_ISSET(h, &writefds))
    		{
    			type = READ_EVENT;
    		}
    		else if (FD_ISSET(h, &exceptfds))
    			printf("!Socket error: %ld\n", WSAGetLastError());
    
    		if (type != INVALID_EVENT)
    		{
    			EventHandler *eh = getItsEventHandler(h);
    			if (eh != NULL) eh->handleEvent(h, type);
    		}
    	}
    }
    else
    { 
    	printf("!Server select error: %ld.\n", WSAGetLastError());
    	Sleep(2000);
    }
    //#]
}

void SocketReactorImplementation::addHandle(HANDLE handle, const Event_Type& type) {
    //#[ operation addHandle(HANDLE,Event_Type)
    if (handles == 0) 
    	handles = new HANDLE[256];
    if (numHandles < 256)
    {
    	SOCKET socket = (SOCKET)handle;
    	printf("addHandle socket %d, Type %d\n", socket, type); 
    	handles[numHandles] = handle;
    	switch (type)
    	{
    		// Receiving data
    		case READ_EVENT:
    			FD_SET(socket, &writefds);
    			FD_SET(socket, &exceptfds);
    			break;
    		// New connection
    		case ACCEPT_EVENT:
    			FD_SET(socket, &readfds);
    			FD_SET(socket, &exceptfds);
    			break;
    		default:
    			FD_SET(socket, &exceptfds);
    	}
    	numHandles++;
    }
    //#]
}

FD_SET SocketReactorImplementation::getExceptfds() const {
    return exceptfds;
}

void SocketReactorImplementation::setExceptfds(FD_SET p_exceptfds) {
    exceptfds = p_exceptfds;
}

FD_SET SocketReactorImplementation::getReadfds() const {
    return readfds;
}

void SocketReactorImplementation::setReadfds(FD_SET p_readfds) {
    readfds = p_readfds;
}

FD_SET SocketReactorImplementation::getWritefds() const {
    return writefds;
}

void SocketReactorImplementation::setWritefds(FD_SET p_writefds) {
    writefds = p_writefds;
}

SocketReactorImplementation::~SocketReactorImplementation() {
    //#[ operation ~SocketReactorImplementation()
    delete handles;
    
    //#]
}

HANDLE* SocketReactorImplementation::getHandles() const {
    return handles;
}

void SocketReactorImplementation::setHandles(HANDLE* p_handles) {
    handles = p_handles;
}

int SocketReactorImplementation::getNumHandles() const {
    return numHandles;
}

void SocketReactorImplementation::setNumHandles(int p_numHandles) {
    numHandles = p_numHandles;
}

// LogAcceptor

/*********************************************************************
	File Path	: DefaultComponent\CodeConfig\SocketReactorImplementation.cpp
*********************************************************************/
